package com.efast.dmom.aps.service.impl;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.efast.dmom.aps.bean.PlanOrder;
import com.efast.dmom.aps.bean.PlanOrderAdjust;
import com.efast.dmom.aps.bean.PlanOrderAdjustQueryCondition;
import com.efast.dmom.aps.bean.PlanOrderAdjustQueryData;
import com.efast.dmom.aps.bean.PlanOrderOperation;
import com.efast.dmom.aps.bean.PlanOrderReorganization;
import com.efast.dmom.aps.bean.ResultBean;
import com.efast.dmom.aps.constant.ServiceConstants;
import com.efast.dmom.aps.datahandlers.PlanOrderDataHandler;
import com.efast.dmom.aps.datahandlers.PlanOrderOperationDataHandler;
import com.efast.dmom.aps.datahandlers.PlanOrderReorganizationDataHandler;
import com.efast.dmom.aps.entity.PlanOrderEntity;
import com.efast.dmom.aps.entity.PlanOrderOperationEntity;
import com.efast.dmom.aps.entity.PlanOrderReorganizationEntity;
import com.efast.dmom.aps.service.PlanOrderService;

@Service
public class PlanOrderServiceImpl implements PlanOrderService {

	@Autowired
	private PlanOrderDataHandler planOrderDataHandler;
	@Autowired
	private PlanOrderReorganizationDataHandler planOrderReorganizationDataHandler;

	@Autowired
	private PlanOrderOperationDataHandler planOrderOperationDataHandler;

	@Override
	public List<PlanOrder> getUnbroadcastPlanOrders(long prodLineKey) {
		return planOrderDataHandler.getUnbroadcastPlanOrders(prodLineKey);
	}

	@Override
	public boolean mergeCheck(List<PlanOrder> planOrderList) {
		if (planOrderList == null || planOrderList.size() < 2) {
			return false;
		}
		String partNoMerge = null;
		String partRevisionMerge = null;
		for (PlanOrder planOrder : planOrderList) {

			String partNo = planOrder.getInnerData().getPartNo();
			String partRevision = planOrder.getInnerData().getPartRevision();
			if (partNo == null || partRevision == null) {
				return false;
			}
			if (partNoMerge == null) {
				partNoMerge = partNo;
				partRevisionMerge = partRevision;
			} else {
				if (!partNoMerge.equals(partNo) || !partRevisionMerge.equals(partRevision)) {
					return false;
				}

			}
		}
		return true;
	}

	public ResultBean getReorganization(long id) {
		ResultBean result = new ResultBean(true, "");
		List<PlanOrderReorganization> byChildOrderId = planOrderReorganizationDataHandler.getByChildOrderId(id);
		if (byChildOrderId != null && byChildOrderId.size() > 0) {
			if (byChildOrderId.size() == 1) {
				result.setSuccess(false);
				result.setMessage("工单是拆单后的计划工单！");
			} else {
				result.setSuccess(false);
				result.setMessage("工单是合并后的计划工单！");
			}
		} else {
			result.setSuccess(true);
		}
		return result;
	}

	@Override
	public ResultBean mergePlanOrder(List<PlanOrder> planOrderList) {
		ResultBean result = new ResultBean(true, "");
		if (planOrderList == null || planOrderList.size() < 2) {
			result.setSuccess(false);
			result.setMessage("合并的工单数量小于2！");
			return result;
		}
		boolean mergeCheck = mergeCheck(planOrderList);
		if (!mergeCheck) {
			result.setSuccess(false);
			result.setMessage("合并的工单物料号不完全一样！");
			return result;
		}
		for (PlanOrder po : planOrderList) {
			ResultBean reorganization = getReorganization(po.getInnerData().getId());
			if (!reorganization.isSuccess()) {
				result.setSuccess(false);
				result.setMessage(reorganization.getMessage());
				return result;
			}
		}
		sortPlanOrderByOfflineDataAndPriority(planOrderList);
		PlanOrder planOrder = planOrderList.get(0);
		PlanOrderEntity tmpEntity = planOrder.getInnerData();

		PlanOrder planOrderNew = new PlanOrder();
		PlanOrderEntity newEntity = new PlanOrderEntity();
		
		String[] orderNo = getOrderNo(tmpEntity.getOrderNumber(),1);
		
		newEntity.setOrderNumber(orderNo[0]);
		newEntity.setPartNo(tmpEntity.getPartNo());
		newEntity.setPartRevision(tmpEntity.getPartRevision());
		newEntity.setPartDesc(tmpEntity.getPartDesc());
		newEntity.setPlanOfflineDate(tmpEntity.getPlanOfflineDate());
		newEntity.setPlantId(tmpEntity.getPlantId());

		int priority = 0;
		int quantity = 0;
		for (PlanOrder po : planOrderList) {

			quantity += po.getInnerData().getQuantity();
			// 数量越大优先级越高
			int pri = po.getInnerData().getPriority();
			if (priority == 1) {
				priority = pri;
			} else {
				if (pri < priority) {
					priority = pri;
				}
			}
		}
		newEntity.setPriority(priority);
		newEntity.setQuantity(quantity);
		newEntity.setOrderStatus(ServiceConstants.APS_PLAN_ORDER_STATUS_CREATED);
		planOrderNew.setInnerData(newEntity);
		planOrderDataHandler.save(planOrderNew);

		PlanOrder byOrderNo = planOrderDataHandler.getByOrderNo(newEntity.getOrderNumber());

		mergePlanOrderHistory(planOrderList, byOrderNo);

		result.setSuccess(true);
		result.setMessage("合单成功！");
		return result;
	}
	private String[] getOrderNo(String orderNo,int i) {
		if(i<1) {
			i=1;
		}
		int length = Integer.toString(i).length();
		if(length <2) {
			length=2;
		}
		String orderNoItem = orderNo+String.format("%0"+length+"d", i++);
		
		PlanOrder byOrderNo = planOrderDataHandler.getByOrderNo(orderNoItem);
		if(byOrderNo!=null && byOrderNo.getInnerData()!=null) {
			String[] orderNo2 = getOrderNo(orderNo,i);
			orderNoItem = orderNo2[0];
			i = Integer.valueOf(orderNo2[1]);
		}
		
		return new String[] {orderNoItem,Integer.toString(i)};
		
	}
	
	private void mergePlanOrderHistory(List<PlanOrder> planOrderList, PlanOrder orderNew) {
		for (PlanOrder po : planOrderList) {

			PlanOrderReorganization por = new PlanOrderReorganization();
			PlanOrderReorganizationEntity pore = new PlanOrderReorganizationEntity();

			pore.setReorganizationType("MERGE");
//			int level = planOrderReorganizationDataHandler.getReorganizationLevelByPlanOrderId(po.getInnerData().getId());
			int level = 1;
			pore.setReorganizationLevel(level + 1);

			pore.setParentPlanOrderId(po.getInnerData().getId());
			pore.setParentPlanOrderNo(po.getInnerData().getOrderNumber());
			pore.setParentPlanOrderPartNo(po.getInnerData().getPartNo());
			pore.setParentPlanOrderPartDesc(po.getInnerData().getPartDesc());
			pore.setParentPlanOrderPriority(po.getInnerData().getPriority());
			pore.setParentPlanOrderQty(po.getInnerData().getQuantity());

			pore.setChildPlanOrderId(orderNew.getInnerData().getId());
			pore.setChildPlanOrderNo(orderNew.getInnerData().getOrderNumber());
			pore.setChildPlanOrderPartNo(orderNew.getInnerData().getPartNo());
			pore.setChildPlanOrderPartDesc(orderNew.getInnerData().getPartDesc());
			pore.setChildPlanOrderPriority(orderNew.getInnerData().getPriority());
			pore.setChildPlanOrderQty(orderNew.getInnerData().getQuantity());

			por.setInnerData(pore);
			planOrderReorganizationDataHandler.save(por);

			po.getInnerData().setOrderStatus(ServiceConstants.APS_PLAN_ORDER_STATUS_MERGED);
			planOrderDataHandler.update(po);
		}

	}

	private void splitPlanOrderHistory(PlanOrder order, PlanOrder orderNew) {

		PlanOrderReorganization por = new PlanOrderReorganization();
		PlanOrderReorganizationEntity pore = new PlanOrderReorganizationEntity();

		pore.setReorganizationType("SPLIT");
//			int level = planOrderReorganizationDataHandler.getReorganizationLevelByPlanOrderId(po.getInnerData().getId());
		int level = 1;
		pore.setReorganizationLevel(level + 1);

		pore.setParentPlanOrderId(order.getInnerData().getId());
		pore.setParentPlanOrderNo(order.getInnerData().getOrderNumber());
		pore.setParentPlanOrderPartNo(order.getInnerData().getPartNo());
		pore.setParentPlanOrderPartDesc(order.getInnerData().getPartDesc());
		pore.setParentPlanOrderPriority(order.getInnerData().getPriority());
		pore.setParentPlanOrderQty(order.getInnerData().getQuantity());

		pore.setChildPlanOrderId(orderNew.getInnerData().getId());
		pore.setChildPlanOrderNo(orderNew.getInnerData().getOrderNumber());
		pore.setChildPlanOrderPartNo(orderNew.getInnerData().getPartNo());
		pore.setChildPlanOrderPartDesc(orderNew.getInnerData().getPartDesc());
		pore.setChildPlanOrderPriority(orderNew.getInnerData().getPriority());
		pore.setChildPlanOrderQty(orderNew.getInnerData().getQuantity());

		por.setInnerData(pore);
		planOrderReorganizationDataHandler.save(por);

	}

	@Override
	public ResultBean splitPlanOrder(PlanOrder planOrder, List<Double> qty) {
		ResultBean result = new ResultBean(true, "");

		PlanOrderEntity mainOrderEntity = planOrder.getInnerData();
		
		double quantity2 = mainOrderEntity.getQuantity();
		double qtyTotal = 0;
		for (double quantity : qty) {
			qtyTotal += quantity;
		}
		if (qtyTotal != quantity2) {
			result.setSuccess(false);
			result.setMessage("拆分的总数和工单的总数不一致！");
			return result;
		}
		ResultBean reorganization = getReorganization(mainOrderEntity.getId());
		if (!reorganization.isSuccess()) {
			result.setSuccess(false);
			result.setMessage(reorganization.getMessage());
			return result;
		}
		for (int i = 0; i < qty.size(); i++) {
			double quantity = qty.get(i);
			PlanOrder po = new PlanOrder();
			PlanOrderEntity entity = new PlanOrderEntity();
			
			String[] orderNo = getOrderNo(mainOrderEntity.getOrderNumber(),i+1);
			
			entity.setOrderNumber(orderNo[0]);
			entity.setPartNo(mainOrderEntity.getPartNo());
			entity.setPartDesc(mainOrderEntity.getPartDesc());
			entity.setPriority(mainOrderEntity.getPriority());
			entity.setPartRevision(mainOrderEntity.getPartRevision());
			entity.setQuantity((int) quantity);
			entity.setPlantId(mainOrderEntity.getPlantId());
			entity.setPlanOfflineDate(mainOrderEntity.getPlanOfflineDate());
			entity.setOrderStatus(ServiceConstants.APS_PLAN_ORDER_STATUS_CREATED);
			po.setInnerData(entity);
			planOrderDataHandler.save(po);
			po = planOrderDataHandler.getByOrderNo(entity.getOrderNumber());
			splitPlanOrderHistory(planOrder, po);

		}
		planOrder.getInnerData().setOrderStatus(ServiceConstants.APS_PLAN_ORDER_STATUS_SPLITED);
		planOrderDataHandler.update(planOrder);
		result.setSuccess(true);
		result.setMessage("拆单成功！");
		return result;
	}

	@Override
	public ResultBean holdPlanOrder(List<PlanOrder> planOrderList, String reason) {
		ResultBean result = new ResultBean(true, "");
		for (PlanOrder po : planOrderList) {
			po.getInnerData().setOrderStatus(ServiceConstants.APS_PLAN_ORDER_STATUS_FREEZE);
			planOrderDataHandler.update(po);
			addPlanOrderOperationHistory(po, "HOLD", reason);
		}
		result.setMessage("已冻结");
		return result;
	}

	private void addPlanOrderOperationHistory(PlanOrder po, String operation, String reason) {
		PlanOrderOperationEntity entity = new PlanOrderOperationEntity();

		entity.setPlanOrderId(po.getInnerData().getId());
		entity.setPlanOrderNo(po.getInnerData().getOrderNumber());
		entity.setPlanOrderPartNo(po.getInnerData().getPartNo());
		entity.setPlanOrderPartDesc(po.getInnerData().getPartDesc());
		entity.setPriority(po.getInnerData().getPriority());
		entity.setQty((double) po.getInnerData().getQuantity());
		entity.setPreviousStatus(po.getInnerData().getOrderStatus() + "");
		entity.setOperation(operation);
		entity.setReason(reason);
		PlanOrderOperation obj = new PlanOrderOperation();
		obj.setInnerData(entity);
		planOrderOperationDataHandler.save(obj);
	}

	@Override
	public ResultBean unholdPlanOrder(List<PlanOrder> planOrderList, String reason) {
		ResultBean result = new ResultBean(true, "");
		for (PlanOrder po : planOrderList) {
			po.getInnerData().setOrderStatus(ServiceConstants.APS_PLAN_ORDER_STATUS_CREATED);
			po.getInnerData().setScheudledOnlineDate(null);
			po.getInnerData().setScheudledOfflineDate(null);
			po.getInnerData().setShopId(0);
			po.getInnerData().setProdLineId(0);
			planOrderDataHandler.update(po);
			addPlanOrderOperationHistory(po, "UNHOLD", reason);
		}
		result.setMessage("已解冻");
		return result;
	}

	@Override
	public ResultBean auditPlanOrder(List<PlanOrder> planOrderList) {
		ResultBean result = new ResultBean(true, "");
		for (PlanOrder po : planOrderList) {
			po.getInnerData().setOrderStatus(ServiceConstants.APS_PLAN_ORDER_STATUS_AUDIT);
			planOrderDataHandler.update(po);
			addPlanOrderOperationHistory(po, "APPROVE", "");
		}
		result.setMessage("已审核");
		return result;
	}

	@Override
	public ResultBean unAuditPlanOrder(List<PlanOrder> planOrderList, String reason) {
		ResultBean result = new ResultBean(true, "");
		for (PlanOrder po : planOrderList) {
			po.getInnerData().setOrderStatus(ServiceConstants.APS_PLAN_ORDER_STATUS_SCHEDULED);
			planOrderDataHandler.update(po);
			addPlanOrderOperationHistory(po, "UNAPPROVE", reason);
		}
		result.setMessage("已审核");
		return result;
	}

	@Override
	public ResultBean rollbackPlanOrder(PlanOrder planOrder, String type) {
		ResultBean result = new ResultBean(true, "");
		if ("MERGE".equals(type)) {
			List<PlanOrderReorganization> byChildOrderId = planOrderReorganizationDataHandler
					.getByChildOrderId(planOrder.getInnerData().getId());
			for (PlanOrderReorganization por : byChildOrderId) {
				long parentPlanOrderId = por.getInnerData().getParentPlanOrderId();
				PlanOrder po = planOrderDataHandler.getById(parentPlanOrderId);
				po.getInnerData().setOrderStatus(ServiceConstants.APS_PLAN_ORDER_STATUS_CREATED);
				planOrderDataHandler.update(po);
				planOrderReorganizationDataHandler.delete(por);
			}
			planOrderDataHandler.delete(planOrder);
			result.setSuccess(true);
			result.setMessage("取消合并成功！");
		} else if ("SPLIT".equals(type)) {
			List<PlanOrderReorganization> pors = planOrderReorganizationDataHandler
					.getByParentOrderId(planOrder.getInnerData().getId());
			for (PlanOrderReorganization por : pors) {
				long poId = por.getInnerData().getChildPlanOrderId();
				PlanOrder po = planOrderDataHandler.getById(poId);
				// po.getInnerData().setOrderStatus(ServiceConstants.APS_PLAN_ORDER_STATUS_CREATED);
				planOrderDataHandler.delete(po);
				planOrderReorganizationDataHandler.delete(por);
			}
//			PlanOrder po = new PlanOrder();
//			PlanOrderEntity entity = new PlanOrderEntity();
//			entity.setId(pors.get(0).getInnerData().getParentPlanOrderId());
//			entity.setOrderStatus(ServiceConstants.APS_PLAN_ORDER_STATUS_CREATED);
//			po.setInnerData(entity);
			PlanOrder po = planOrderDataHandler.getById(pors.get(0).getInnerData().getParentPlanOrderId());
			po.getInnerData().setOrderStatus(ServiceConstants.APS_PLAN_ORDER_STATUS_CREATED);
			planOrderDataHandler.update(po);

			result.setSuccess(true);
			result.setMessage("取消分解成功！");
		} else {
			result.setSuccess(false);
			result.setMessage("无效的类型，不是合并也不是拆分！");
		}
		return result;
	}

	@Override
	public PlanOrderAdjustQueryData getDataByPlanOrderAdjust(
			PlanOrderAdjustQueryCondition planOrderAdjustQueryCondition) {
		if (planOrderAdjustQueryCondition.getLength() == 0) {
			planOrderAdjustQueryCondition.setLength(10);
		}
		if (planOrderAdjustQueryCondition.getStart() == 1) {
			planOrderAdjustQueryCondition.setStart(0);
		} else if (planOrderAdjustQueryCondition.getStart() > 1) {
			planOrderAdjustQueryCondition.setStart(
					(planOrderAdjustQueryCondition.getStart() - 1) * planOrderAdjustQueryCondition.getLength());
		}
		PlanOrderAdjustQueryData data = new PlanOrderAdjustQueryData();
		List<PlanOrderAdjust> adjustList = planOrderDataHandler.getDataByPlanOrderAdjust(planOrderAdjustQueryCondition);
		planOrderAdjustQueryCondition.setStart(0);
		planOrderAdjustQueryCondition.setLength(0);
		List<PlanOrderAdjust> adjustSize = planOrderDataHandler.getDataByPlanOrderAdjust(planOrderAdjustQueryCondition);
		if (adjustList != null && adjustSize != null) {
			data.setCountSize(adjustSize.size());
			data.setList(adjustList);
		}
		return data;
	}
	
	// sort plan order by plan offline date and priority
	public List<PlanOrder> sortPlanOrderByOfflineDataAndPriority(List<PlanOrder> listData) {
		Collections.sort(listData, new Comparator<PlanOrder>() {
			@Override
			public int compare(PlanOrder order1, PlanOrder order2) {
				PlanOrderEntity entity1 = order1.getInnerData();
				PlanOrderEntity entity2 = order2.getInnerData();
				if (entity1 == null) {
					return -1;
				}
				if (entity2 == null) {
					return -1;
				}
				if (entity1.getPlanOfflineDate() == null) {
					return -1;
				}
				if (entity2.getPlanOfflineDate() == null) {
					return -1;
				}
				if (entity1.getPlanOfflineDate().isBefore(entity2.getPlanOfflineDate()))
					return -1;
				else if (entity1.getPlanOfflineDate().isAfter(entity2.getPlanOfflineDate())) {
					return 1;
				} else if (entity1.getPlanOfflineDate().equals(entity2.getPlanOfflineDate())) {
					if (entity1.getPriority() > entity2.getPriority()) {
						return -1;
					}
					if (entity1.getPriority() < entity2.getPriority()) {
						return 1;
					}
				}
				return 0;
			}

		});
		return listData;
	}
}
